package com.jc.utils;

import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorFactory;

/**
 * 系统中URL传递参数的构造解析:不支持组合属性
 * 
 * @author wb-lixiaolong
 * 
 */
public class URLParamsParseUtil {
    
    private static final Log LOG = LogFactory.getLog(URLParamsParseUtil.class);
    /**
     * 根据属性名-属性值键值对设置指定对象的属性值
     * 
     * @param obj
     * @param propertyValues
     * @return
     */
    public static Object setPropertyValues(Object obj, Map<String, Object> propertyValues) {
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(obj);
        MutablePropertyValues pvs = new MutablePropertyValues();
        pvs.addPropertyValues(propertyValues);
        bw.setPropertyValues(pvs, true);
        return obj;
    }

    /**
     * 获取指定对象的属性描述数组
     * 
     * @param obj
     * @return
     */
    public static PropertyDescriptor[] getPropertyDescriptors(Object obj) {
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(obj);
        return bw.getPropertyDescriptors();
    }

    /**
     * 获取指定对象的 属性名-属性值键值对
     * 
     * @param obj
     * @return
     */
    public static Map<String, Object> getPropertyKeyValues(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        PropertyDescriptor[] pds = getPropertyDescriptors(obj);
        for (PropertyDescriptor pd : pds) {
            map.put(pd.getName(), pd.getValue(pd.getName()));
        }
        return map;
    }

    /**
     * 构造指定对象属性的URL参数格式：property1=value1&property2=value2
     * 
     * @param obj
     * @return
     */
    public static String parseObj2URLParams(Object obj) {
        if (null == obj) {
            return "";
        }

        StringBuffer sb = new StringBuffer();
        PropertyDescriptor[] pds = getPropertyDescriptors(obj);
        for (PropertyDescriptor pd : pds) {
            Object value = null;
            try {
                value = pd.getReadMethod().invoke(obj);
                if (null != value && isPrimitiveOrStringType(value)) {
                    sb.append(pd.getName()).append("=").append(value).append("&");
                }
            } catch (Exception e) {
                LOG.error("parseObj2URLParams create error", e);
            }
        }
        return sb.length() == 0 ? "" : sb.subSequence(0, sb.length() - 1).toString();
    }

    /**
     * 判断一个对象是否为基本类型或者String类型
     * 
     * @param obj
     * @return
     */
    public static boolean isPrimitiveOrStringType(Object obj) {
        if (null == obj) {
            return false;
        }

        Class<? extends Object> type = obj.getClass();
        if (type.isPrimitive()) {
            return true;
        }
        if (Number.class.isAssignableFrom(type)) {
            return true;
        }
        if (String.class.isAssignableFrom(type)) {
            return true;
        }

        return false;
    }
}
